package com.icesoft.core.web.suppose.upload.config;

import com.icesoft.core.common.util.RegexUtils;
import com.icesoft.core.web.suppose.setting.BasePropertySetting;
import com.icesoft.core.web.suppose.setting.BaseSettingEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
@Slf4j
public class FileUploadPropertySetting extends BasePropertySetting<FileUploadPropertySetting.SettingEnum>
		implements ApplicationRunner {

	public static final String LOGIN_SETTING_GROUP_NAME = "上传配置";

	@Override
	public String getGroupName() {
		return LOGIN_SETTING_GROUP_NAME;
	}

	public boolean isWhiteExt(String page, String fileName) {
		String extName = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
		if (!RegexUtils.isEngAndNum(extName)) {
			log.warn("后缀：{}不合法", extName);
			return false;
		} else {
			if (!whiteExts.contains(extName)) {
				log.warn("未被允许的后缀：{}", extName, page);
				return false;
			}
			if (page == null) {
				page = "null";
				log.trace("校验后缀：{}", extName);
			} else {
				page = page.substring(page.lastIndexOf("/") + 1);
				log.trace("校验页面：{}，后缀：{}", page, extName);
			}

			HashSet<String> pageExts = pageMapExts.get(page);
			if (pageExts != null && !pageExts.contains(extName)) {
				log.warn("后缀：{}不被页面：{}允许", extName, page);
				return false;
			}
			log.trace("页面{}后缀未做指定，后缀：{}", page, extName);
		}

		return true;
	}

	HashSet<String> whiteExts;
	Map<String, HashSet<String>> pageMapExts;

	@Override
	public void run(ApplicationArguments args) throws Exception {
		refresh();
	}

	void refresh() {
		whiteExts = new HashSet<>();
		pageMapExts = new HashMap<>();
		Map<String, String> map = getProperties();
		for (SettingEnum[] settingEnums : pageExtEnums) {
			String pagesStr = map.get(settingEnums[0].name());
			String extsStr = map.get(settingEnums[1].name());
			if (pagesStr == null || extsStr == null) {
				continue;
			}
			List<String> exts = Arrays.asList(extsStr.split(","));
			if (!StringUtils.isBlank(pagesStr)) {
				String[] pages = pagesStr.split(",");
				for (String page : pages) {
					HashSet<String> extList = pageMapExts.getOrDefault(page, new HashSet<>());
					extList.addAll(exts);
					pageMapExts.put(page, extList);
				}
			}
			whiteExts.addAll(exts);
		}

		String referrerPageExt = map.get(SettingEnum.bc_file_referrerPageExt.name());
		String[] arr = referrerPageExt.split(",");
		for (String str : arr) {
			String settingEnums[] = str.split(":");
			if (settingEnums.length != 2) {
				log.warn(SettingEnum.bc_file_referrerPageExt.name() + "配置错误：" + referrerPageExt);
				break;
			}
			String pagesStr = settingEnums[0];
			String extsStr = settingEnums[1];
			List<String> exts = Arrays.asList(StringUtils.split(extsStr, "|"));
			if (!StringUtils.isBlank(pagesStr)) {
				String[] pages = StringUtils.split(pagesStr, "|");
				for (String page : pages) {
					HashSet<String> extList = pageMapExts.getOrDefault(page, new HashSet<>());
					extList.addAll(exts);
					pageMapExts.put(page, extList);
				}
			}

			whiteExts.addAll(exts);
		}

		log.debug("白名单后缀：{},指定页面后缀:{}", whiteExts, pageMapExts);
	}

	static SettingEnum[][] pageExtEnums = new SettingEnum[][] {
			{ SettingEnum.bc_file_imageExtPage, SettingEnum.bc_file_imageExt },
			{ SettingEnum.bc_file_videoExtPage, SettingEnum.bc_file_videoExt },
			{ SettingEnum.bc_file_audioExtPage, SettingEnum.bc_file_audioExt },
			{ SettingEnum.bc_file_compressExtPage, SettingEnum.bc_file_compressExt },
			{ SettingEnum.bc_file_officeExtPage, SettingEnum.bc_file_officeExt },
			{ SettingEnum.bc_file_appExtPage, SettingEnum.bc_file_appExt },
			{ SettingEnum.bc_file_otherExtPage, SettingEnum.bc_file_otherExt } };

	enum SettingEnum implements BaseSettingEnum {

		bc_file_extDes("无用配置, 后缀配置的说明，以下指定的页面配置为或条件", "没有配置的页面上传后缀必须是以下所有后缀中的一个"),

		bc_file_imageExt("图片后缀，用英文“,”分隔", "jpeg,jpg,gif,png,bmp,psd"), bc_file_imageExtPage("允许上传图片的页面",
				"sysUser-edit.html,appUser-edit.html"),

		bc_file_videoExt("视频后缀，用英文“,”分隔", "mp4,rmvb,avi,wma,rm,flash,3gp,mpeg,flv"), bc_file_videoExtPage("允许上传视频的页面",
				"video.html"),

		bc_file_audioExt("音频后缀，用英文“,”分隔", "wav,aac,amr,mp3"), bc_file_audioExtPage("允许上传音频的页面", "music.html"),

		bc_file_compressExt("压缩文件后缀，用英文“,”分隔", "rar,zip,7z"), bc_file_compressExtPage("允许上传压缩文件的页面", "attachment.html"),

		bc_file_officeExt("office文件后缀，用英文“,”分隔",
				"xls,xlsx,csv,pdf,docx,doc,ppt,pptx,txt"), bc_file_officeExtPage("允许上传office文件的页面", "office.html"),

		bc_file_appExt("app文件后缀，用英文“,”分隔", "apk,ipa"), bc_file_appExtPage("允许app文件后缀的页面", "app.html"),

		bc_file_otherExt("其他允许上传的文件后缀，用英文“,”分隔", "other"), bc_file_otherExtPage("允许其他后缀的页面", "other.html"),

		bc_file_referrerPageExt("指定页面允许上传的后缀，“|”表示或，每一组用英文“,”分隔", "uploadexcel.html|excel.html:xls|xlsx");

		private String des;
		private String defaultValue;

		SettingEnum(String des, String defaultValue) {
			this.des = des;
			this.defaultValue = defaultValue;
		}

		@Override
		public String getDes() {
			return this.des;
		}

		@Override
		public String getDefaultValue() {
			return this.defaultValue;
		}
	}

}
